<!--
 * @Author: weidewei
 * @Date: 2025-11-11 09:16:17
 * @LastEditors: weidewei
 * @LastEditTime: 2025-11-11 17:03:37
 * @Description: 
 * @FilePath: \2025-front-face\review-knowledge\20251110\复习手写Promise A+规范.html
-->
<script>
  /**
   * 1. 实现状态的变化
   * 2. 创建then函数
   * 3. 生成执行队列: 添加执行队列 应该每一个对象：每个执行器函数，状态，成功的方法，失败的方法
   * 4. 遍历执行队列
   *
   */

  function isPromise(obj) {
    return !!(
    obj && 
      (typeof obj === "object" || typeof obj === "function") && 
      typeof obj.then === "function"
    );
  }

  function runMicroTask(callback) {
    if (MutationObserver) {
      const div = document.createElement("div");
      const observer = new MutationObserver(callback);
      observer.observe(div, {
        childList: true,
      });
      div.innerHTML = "js";
    } else if (process && process.nextTick) {
      process.nextTick(callback);
    } else {
      setTimeout(callback, 0);
    }
  }

  const FULFILLED = "fulfilled";
  const PENDING = "pending";
  const REJECTED = "rejected";
  class MyPromise {
    #state;
    #value;
    #handlers;
    constructor(executor) {
      try {
        this.#state = PENDING;
        this.#value = undefined;
        // 里面应该有执行器，状态，成功执行的方法，失败执行的方法
        this.#handlers = [];
        executor(this.#resolve.bind(this), this.#reject.bind(this));
      } catch (err) {
        console.error(err);
        this.#reject(err);
      }
    }
    // 添加任务队列
    #pushHandler(executor, state, resolve, reject) {
      this.#handlers.push({
        executor,
        state,
        resolve,
        reject,
      });
    }

    // 执行任务队列： 执行完一个任务队列就删掉,往前面删
    #runHandlers() {
      // 这个判断不加的话会导致第一个then如果返回Promise的resolve的值第二个then拿不到值
      if (this.#state === PENDING) return;
      while (this.#handlers[0]) {
        const handler = this.#handlers[0];
        this.#runOneHandler(handler);
        this.#handlers.shift();
      }
      /* const handler = this.#handlers[0]; 
      while(handler) { // 这样会导致死循环
        this.#runOneHandler(handler); 
        this.#handlers.shift();
      } */
    }

    #runOneHandler({ executor, state, resolve, reject }) {
      // 放到微队列里面执行
      runMicroTask(() => {
        // 状态不一致，不处理
        if (state !== this.#state) return;
        if (typeof executor !== "function") {
          // 传递后续处理并非一个函数，要进行状态穿透
          this.#state === FULFILLED
            ? resolve(this.#value)
            : reject(this.#value);
          return;
        }
        try {
          // 如果传的executor是一个函数那就直接调用
          const result = executor(this.#value);
          if (isPromise(result)) {
            result.then(resolve, reject);
          } else {
            // 如果是前一个then有返回值,就传给下一个then
            resolve(result);
          }
        } catch (err) {
          reject(err);
        }
      });
    }

    #resolve(data) {
      this.#setState(FULFILLED, data);
    }
    #reject(reason) {
      this.#setState(REJECTED, reason);
    }

    then(onFulfilled, onRejected) {
      return new MyPromise((resolve, reject) => {
        this.#pushHandler(onFulfilled, FULFILLED, resolve, reject);
        this.#pushHandler(onRejected, REJECTED, resolve, reject);
        this.#runHandlers();
      });
    }

    #setState(state, value) {
      if (this.#state !== PENDING) return; // Promise的状态不可逆
      this.#state = state;
      this.#value = value;
      this.#runHandlers();
    }
  }

  const p = new MyPromise((resolve, reject) => {
    resolve(222);
  }).then(data=>{
    console.log('then',data);
    // return 'xxx'; // 对应传的不是promiseLike的处理
    return new MyPromise((resolve,reject)=>{
      resolve(666);
    })
  }).then(data=>{
    console.log('then2',data)
  });

  /* 微任务队列测试 
  console.log(1);
  setTimeout(() => {
    console.log(2);
  }, 0);
  runMicroTack(()=>{
    console.log(3);
  }) */
</script>
